<template>
    <div class="action-block" ref="box"
         :style="{
           width:`${actionWidth}px`,
           left:`${actionLeft}px`,
           top: `${blockData?(blockData.top?blockData.top+'px':defaultTop+'px'):'0px'}`,
         }">
        <div class="action-box">
            <!--用于拉伸X 坐标，让他变长缩短-->
            <div class="left-box action" v-if="enableDragSide" @mousedown="onMouseLineDown($event,-1)"  @contextmenu.prevent="()=>{}"></div>

            <!--时间块的具体内容 拖拽事件-->
            <div class="action-content" @mousedown="enableDragFree?onMouseFreeDown($event):null">
                <slot></slot>
            </div>
            <!--用于拉伸X 坐标，让他变长缩短-->
            <div class="right-box action" v-if="enableDragSide" @mousedown="onMouseLineDown($event,1)"  @contextmenu.prevent="()=>{}"></div>
        </div>
    </div>
</template>

<script>
    import {EventBus,getAbsTop,getAbsLeft} from "@/common/js/util"
    export default {
        name: "action-block",
        props: {
            //时间块数据
            blockData: {
                type: Object,
                default: ()=>{}
            },
            // 行数据
            rowData: {
                type: Object,
                default: ()=>{}
            },
            // 所有数据
            ganttData: {
              type: Array,
              default: ()=>[]
            },
            //在外头选择的时间
            choiceTime: {
                type: Array,
                default: ()=>[]
            },
            //左右可拖拽
            enableDragSide: {
                type: Boolean,
                default: false
            },
            //是否允许自由拖拽，但是该组件的自由拖拽不进行真实交互，只是回调事件
            enableDragFree: {
                type: Boolean,
                default: false
            },
            //开始时间的字段
            startTimeCol: {
                type: String,
                default: 'startTime'
            },
            //结束时间的字段
            endTimeCol: {
                type: String,
                default: 'endTime'
            },
            //滚动条的距离
            scrollLeft: {
              type: Number,
              default: 0
            },
        },
        computed: {
            //时间块的宽度
            actionWidth() {
                if(this.blockData) {

                    const startTime = new Date(this.blockData[this.startTimeCol])

                    const endTime = new Date(this.blockData[this.endTimeCol])

                    //计算差值
                    let diffTime = (endTime.getTime() - startTime.getTime())/1000/60
                    return diffTime
                }
                return 0
            },
            //时间块的左边偏移量
            actionLeft() {
                if(this.blockData) {

                    const limitTime = new Date(this.choiceTime[0])

                    const startTime = new Date(this.blockData[this.startTimeCol])

                    //计算时间块的左边距离甘特图边界的距离
                    let diffTime = (startTime.getTime() - limitTime.getTime())/1000/60
                    return diffTime
                }
                return 0
            },
        },
        data() {
            return {
                //默认的高度
                defaultTop: 10,
                mousePosition: {
                    left: 0,
                    right: 0
                },
                uniqueId: 0
            }
        },
        methods: {
            //时间块左右两边的可拖拽滑块 direction: -1 左边；1右边
            onMouseLineDown(e,direction) {

                const startTimeDate = new Date(this.blockData[this.startTimeCol])

                const endTimeDate = new Date(this.blockData[this.endTimeCol])

                let startTime = startTimeDate.getTime()
                let endTime = endTimeDate.getTime()

                //可滚动区域
                let wordDom = document.getElementById('ganttGrid')

                wordDom.onmousemove = (ee) => {

                    // 用鼠标的位置减去鼠标相对元素的位置，得到元素的位置
                    let v = ee.clientX - e.clientX;
                    //v左边移动减少
                    if(direction == -1) {

                        //左边拉长是减少
                        if(this.mousePosition.left < v) {
                            //如果是缩短，那么就可以进行width不为-1的判断了
                            if(this.actionWidth <= 0) {
                                return
                            }
                        }

                        //分钟赋值后，设置成new Date
                        this.blockData[this.startTimeCol] = new Date( startTime + (v * 1000 * 60) ).format("yyyy/MM/dd hh:mm:ss")

                        // 如果拉过头，那么就强制让startTime 与 endTime 一致
                        // 拉过头是因为 this.actionWidth 方法计算是异步的，而v差不多是直接响应出来的，有时候v值是新的，但是actionWidth还是久的，就导致了没能拦住
                        if(this.actionWidth <= 0) {
                            this.blockData[this.startTimeCol] = this.blockData[this.endTimeCol]
                        }

                        this.mousePosition.left = v
                    }
                    //右边移动
                    else if(direction == 1) {

                        //v右边拉长是增加
                        if(this.mousePosition.right > v) {
                            //如果是缩短，那么就可以进行width不为-1的判断了
                            if(this.actionWidth <= 0) {
                                return
                            }
                        }
                        //分钟赋值后，设置成new Date
                        this.blockData[this.endTimeCol] = new Date( endTime + (v * 1000 * 60) ).format("yyyy/MM/dd hh:mm:ss")

                        if(this.actionWidth <= 0) {
                            this.blockData[this.endTimeCol] = this.blockData[this.startTimeCol]
                        }

                        this.mousePosition.right = v

                     }
                }

                window.onmouseup = ()=>{

                    //执行回调，让回调的地方进行http调用
                    this.$emit('moveSideChange',this.blockData)

                    wordDom.onmousemove = null
                    window.onmouseup = null
                }
            },
            //鼠标自由拖拽用的点下
            onMouseFreeDown(e) {

                // 右键点击的情况下，不触发下列事件
                if(e.button === 2) {
                  return
                }

                this.uniqueId = 0

                const box = this.$refs.box

                //时间块的宽度
                const domWidth = parseInt(box.style.width)

                //复制出一个dom 以此为操作坐标
                const copyDom = box.cloneNode(true);

                //可滚动区域
                const wordDom = document.getElementById('contentGrid')
            

                const diffX =  e.clientX  - box.offsetLeft

                //const diffY = e.clientY - box.offsetTop

                this.$emit("onActionBlockDown")

                let startTime = this.blockData[this.startTimeCol]

                let endTime = this.blockData[this.endTimeCol]


                // 摁下的时候 当前块数据  因为虚拟列表会把这个消化掉 所以需要破绑定一下
                const downBlockData = JSON.parse(JSON.stringify(this.blockData))

                const downRowData =  JSON.parse(JSON.stringify(this.rowData))

                wordDom.onmousemove = (ee) => {
               
                    // 只有第一次移动的时候才创建虚拟dom
                    if(this.uniqueId === 0) {
                      wordDom.appendChild(copyDom)
                      copyDom.style.opacity = "0.5"
                      this.uniqueId ++
                    }

                    const left = ee.clientX - diffX

                    const top = ee.clientY - getAbsTop(wordDom) - 20

                    copyDom.style.left = left - this.scrollLeft + 'px'

                    copyDom.style.top = top + 'px'

                    startTime = new Date(new Date(this.choiceTime[0]).getTime() + (left * 1000 * 60))

                    endTime = new Date(startTime.getTime() + (domWidth * 1000 * 60))

                }

                window.onmouseup = ()=>{

                    const rowData = this.ganttData.find(e => e.id === downRowData.id)
                    const blockData = rowData.timeBlock.find(e => e.id === downBlockData.id)
                    
                    if(this.uniqueId === 0) {
                        wordDom.onmousemove = null
                        window.onmouseup = null
                       
                        // 因为虚拟列表的缘故 window的up事件虽然不至于会被清除  但是 寻常emit/on 事件会失效  所以使用全局的事件总线，全局的emit/on
                        EventBus.$emit('onActionBlockUp', {
                            blockData,
                            rowData
                        })

                        return
                    }

                    
                    wordDom.removeChild(copyDom)

                    this.blockData[this.startTimeCol] = startTime.format("yyyy/MM/dd hh:mm:ss")

                    this.blockData[this.endTimeCol] = endTime.format("yyyy/MM/dd hh:mm:ss")

                    // 因为虚拟列表的缘故 window的up事件虽然不至于会被清除  但是 寻常emit/on 事件会失效  所以使用全局的事件总线，全局的emit/on
                    EventBus.$emit('onActionBlockUp', {
                      blockData,
                      rowData
                    })

                    wordDom.onmousemove = null
                    window.onmouseup = null
                }

            }
        }
    }
</script>

<style scoped lang="scss">
    .action-block {
        position: absolute;
        height: 40px;
        min-height: 40px;
        max-height: 40px;
        background-color: #ffedb3;
        box-sizing: border-box;
        border: 1px solid gold;
        z-index: 3;
        border-radius: 4px;

        .action-box {
            height: 100%;
            display: flex;
            justify-content: space-between;
            .action-content {
                flex: 1;
            }
            .action {
                box-sizing: border-box;
                cursor: pointer;
                padding: 0 5px;
                opacity: 0;
                background-color: rgba(255,255,255,0.5);
                &:hover {
                    opacity: 1;
                }
            }
        }
    }
</style>